﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Resources;
using System.Diagnostics;

namespace ENG.TeachersDiary
{
  class Common
  {
    public static string UserAppDataPath
    {
      get
      {
        string pom = Application.UserAppDataPath;
        pom = System.IO.Path.GetDirectoryName(pom);
        return pom;
      }
    }

    public static int CurrentClassID;
    public static int CurrentSubjectID;

    public static ENG.TeachersDiary.Model.Class GetCurrentClass (ENG.TeachersDiary.Model.DiaryDB db)
    {
      var clss = db.Classes.Where(i => i.ClassID == CurrentClassID);
      var ret = clss.ToArray()[0];
      return ret;
    }
    public static ENG.TeachersDiary.Model.Subject GetCurrentSubject(ENG.TeachersDiary.Model.DiaryDB db)
    {
      var subjs = db.Subjects.Where(i => i.SubjectID == CurrentSubjectID);
      var ret = subjs.ToArray()[0];
      return ret;
    }

    public static IOrderedEnumerable<ENG.TeachersDiary.Model.MarkGroup> GetCurrentMarkGroups(ENG.TeachersDiary.Model.DiaryDB db)
    {
      var cs = GetCurrentSubject(db);

      var ret = cs.MarkGroups.OrderBy(i => i.OrderIndex);

      return ret;
    }


    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
    private static ENG.TeachersDiary.Model.Class _CurrentClass = null;
    ///<summary>
    /// Sets/gets CurrentClass value. Default value is null.
    ///</summary>
    [Obsolete()]
    public static ENG.TeachersDiary.Model.Class CurrentClass
    {
      get
      {
        return GetCurrentClass(DBConn);
      }
      set
      {
        _CurrentClass = value;
      }
    }

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
    private static ENG.TeachersDiary.Model.Subject _CurrentSubject = null;
    ///<summary>
    /// Sets/gets CurrentSubject value. Default value is null.
    ///</summary>
    [Obsolete()]
    public static ENG.TeachersDiary.Model.Subject CurrentSubject
    {
      get
      {
        return GetCurrentSubject(DBConn);
      }
      set
      {
        _CurrentSubject = value;
      }
    }

    private static List<ENG.TeachersDiary.Model.MeanMeaning> currentMeanMeanings = null;
    public static List<ENG.TeachersDiary.Model.MeanMeaning> CurrentMeanMeanings
    {
      get
      {
        if (currentMeanMeanings == null)
          currentMeanMeanings = DBConn.MeanMeanings.OrderBy(i => i.MaxMeanValue).ToList();

        return currentMeanMeanings;
      }
      set
      {
        if (value == null)
          currentMeanMeanings = null;
        else
          throw new Exception("Can be set to null only!");
      }
    }

    private static List<ENG.TeachersDiary.Model.MarkCode> markCodes = null;
    public static List<ENG.TeachersDiary.Model.MarkCode> MarkCodes
    {
      get
      {
        if (markCodes == null)
        {
          markCodes =
            DBConn.MarkCodes.ToList();
        }
        return markCodes;
      }
      set
      {
        if (value == null)
          markCodes = null;
        else
          throw new Exception("You can set only NULL value into mark codes.");
      }
    }
    
    //private static ENG.TeachersDiary.Model.DiaryDB db = null;
    public static ENG.TeachersDiary.Model.DiaryDB DBConn
    {
      get
      {
        ENG.TeachersDiary.Model.DiaryDB db = null;

        string dbFile = ENG.TeachersDiary.Properties.Settings.Default.DBFile;

        if (db == null)
        {
          db = new ENG.TeachersDiary.Model.DiaryDB("Data source=" + dbFile);
        }        

        return db;
      }
    }

    public static void CreateNewDB(string fileName)
    {
      var db = new ENG.TeachersDiary.Model.DiaryDB("Data source=" + fileName);
      db.CreateDatabase();

      Model.MarkCode mc = null;

      mc = new Model.MarkCode();
      mc.Display = "---";
      mc.IsEvaluable = false;
      mc.OrderIndex = 0;
      mc.Value = 0;
      db.MarkCodes.InsertOnSubmit(mc);

      var marks = MarkCodeSet.GetMarkCodeSet(MarkCodeSet.CS);
      int orderIndex = 1;

      foreach (var fItem in marks)
      {
        mc = new Model.MarkCode();
        mc.Display = fItem.Key;
        mc.IsEvaluable = true;
        mc.OrderIndex = orderIndex;
        mc.Value = fItem.Value;
        db.MarkCodes.InsertOnSubmit(mc);

        orderIndex += 1;
      } // foreach (var fItem in marks)

      db.SubmitChanges();
    }

    public static Model.MarkGroup
      CreateDefaultMarkGroupWithoutSubject()
    {
      Model.MarkGroup ret = new Model.MarkGroup();

      ret.Title = Properties.Resources.DefaultMarkGroup;
      ret.Abbr = "()";
      ret.Weight = 1;
      ret.IsDefault = true;
      ret.IsToOffer = true;
      ret.IsEvaluated = true;
      ret.IsLocallySummed = false;

      return ret;
    }

    internal static void DoBackup()
    {
      string backupFileName = System.IO.Path.GetFileNameWithoutExtension(
        Properties.Settings.Default.DBFile);
      backupFileName += "_" + DateTime.Now.ToString("yyyy-MM-ddTHH_mm_ss") + ".sdf";

      string backupPath =
          System.IO.Path.Combine(Common.UserAppDataPath, "Backup");

      try
      {
        System.IO.Directory.CreateDirectory(backupPath);
      }
      catch (Exception ex)
      {
        MessageBox.Show(Properties.Resources.BackupFailedFolder + backupPath + "." + ex.Message,
          Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
      }

      try
      {
        System.IO.File.Copy(
          Properties.Settings.Default.DBFile,
          System.IO.Path.Combine(backupPath, backupFileName));
      }
      catch (Exception ex)
      {
        MessageBox.Show(Properties.Resources.BackupFailedCopy + backupFileName + " ." + ex.Message,
          Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
      }

      Properties.Settings.Default.LastBackupDate = DateTime.Now;
      Properties.Settings.Default.Save();

      string zippedFileName =
        System.IO.Path.GetFileNameWithoutExtension(backupFileName) + ".zip";

      try
      {
        ZipFile(
          System.IO.Path.Combine(backupPath, backupFileName),
          System.IO.Path.Combine(backupPath, zippedFileName));

        System.IO.File.Delete(
          System.IO.Path.Combine(backupPath, backupFileName));
      }
      catch (Exception ex)
      {
        MessageBox.Show(Properties.Resources.BackupDoneWithError + ex.Message,
          Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
        return;
      }

      MessageBox.Show(Properties.Resources.BackupDone,
          Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
    }

    internal static void OpenExplorerForFile(string fileName)
    {
      Process p = new Process();
      ProcessStartInfo ps = new ProcessStartInfo();
      ps.Arguments = "/select, \"" + fileName + "\"";
      ps.FileName = "explorer.exe";

      p.StartInfo = ps;

      p.Start();
    }


    private static void ZipFile(string source, string target)
    {
      Ionic.Zip.ZipFile zf = new Ionic.Zip.ZipFile(target);

      zf.AddFile(source);
      zf.Save();
    }

    private static string GetQuickBackupFileName()
    {
      string ret = System.IO.Path.GetFileNameWithoutExtension(
        Properties.Settings.Default.DBFile);
      ret += "__.sdf";

      return ret;
    }

    internal static void DoQuickBackup()
    {
      string backupFileName = GetQuickBackupFileName();

      string backupPath =
          System.IO.Path.Combine(UserAppDataPath, "Backup");

      try
      {
        System.IO.Directory.CreateDirectory(backupPath);
      }
      catch (Exception ex)
      {
        MessageBox.Show(Properties.Resources.BackupFailedFolder + backupPath + "." + ex.Message,
          Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
      }

      try
      {
        System.IO.File.Copy(
          Properties.Settings.Default.DBFile,
          System.IO.Path.Combine(backupPath, backupFileName), true);
      }
      catch (Exception ex)
      {
        MessageBox.Show(Properties.Resources.BackupFailedCopy + backupFileName + " ." + ex.Message,
          Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
      }


    }

    internal static void RestoreQuitBackup()
    {
      string backupFileName = GetQuickBackupFileName();

      string backupPath =
    System.IO.Path.Combine(UserAppDataPath, "Backup");

      try
      {
        System.IO.File.Copy(
          System.IO.Path.Combine(backupPath, backupFileName),
          Properties.Settings.Default.DBFile,
          true);

        Application.Restart();
      } // try
      catch
      {
        MessageBox.Show(Properties.Resources.QuickBackupRestoreFailed,
          Properties.Resources.ErrorDialogTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
      } // catch (Exception ex)
    }
  }
}
